package zd

import (
	"context"
	"database/sql"
	"database/sql/driver"
	"reflect"
	"unsafe"

	"gitee.com/chunanyong/zorm"
)

// RegNumberType dm 和 oracle Number/Numeric 类型转为 float64
func RegNumberType() {
	//RegisterCustomDriverValueConver 注册自定义的字段处理逻辑,用于驱动无法直接转换的场景,例如达梦的 TEXT 无法直接转化成 string
	//一般是放到init方法里进行注册
	zorm.RegisterCustomDriverValueConver("dm.NUMERIC", NumericType{})
	zorm.RegisterCustomDriverValueConver("dm.NUMBER", NumericType{})
	zorm.RegisterCustomDriverValueConver("oracle.NUMERIC", NumericType{})
	zorm.RegisterCustomDriverValueConver("oracle.NUMBER", NumericType{})
}

type NumericType struct{}

// GetDriverValue 根据数据库列类型,返回driver.Value的实例,struct属性类型
// 非struct类型接收,无法获取到structFieldType,会传入nil
func (e NumericType) GetDriverValue(ctx context.Context, columnType *sql.ColumnType, structFieldType *reflect.Type) (driver.Value, error) {
	return new(float64), nil
}

// ConverDriverValue 数据库列类型,GetDriverValue返回的driver.Value的临时接收值,struct属性类型
// 非struct类型接收,无法获取到structFieldType,会传入nil
// 返回符合接收类型值的指针,指针,指针!!!!
func (e NumericType) ConverDriverValue(ctx context.Context, columnType *sql.ColumnType, tempDriverValue driver.Value, structFieldType *reflect.Type) (any, error) {
	val := tempDriverValue.(*float64)
	if structFieldType != nil {
		// 变量类型为 structFieldType 否则提示类型不匹配
		v := reflect.NewAt(*structFieldType, unsafe.Pointer(val))
		return v.Interface(), nil
	}
	return val, nil
}
